package Components;

import Communication.MyTelnet;
import Configuration.EngineConfiguration;
import Configuration.configuration;
import DEC.DEC;
import Patterns.SymmetrixComponent;
import com.google.gson.annotations.SerializedName;
import org.apache.commons.validator.routines.InetAddressValidator;

/*
 * @author mgrutman
 * @author palugs
 */

public class EthernetSwitch extends SymmetrixComponent
{
    MyTelnet tln = new MyTelnet();
    
    @SerializedName("ip")
    String serverIP;

    public String getServerIP() {
        return serverIP;
    }

    public void setServerIP(String serverIP) {
        this.serverIP = serverIP;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public int getNumEngines() {
        return numEngines;
    }

    public void setNumEngines(int numEngines) {
        this.numEngines = numEngines;
    }

    public int getNumVlans() {
        return numVlans;
    }

    public void setNumVlans(int numVlans) {
        this.numVlans = numVlans;
    }
    
    @SerializedName("port")
    int port = 23; 
    
    int numEngines = 4; 
    
    int numVlans = 3; 
    
    //@SerializedName("Configuration")
    
    public EthernetSwitch(String ip)
    {
        super(EthernetSwitch.class);
        serverIP = InetAddressValidator.getInstance().isValidInet4Address(ip) ? ip : "192.168.177.177";         
    }
    
    public int runCommands (String fname)
    {
        tln.loginEthernetSwitch("manager","friend","manager >");
        tln.runTelnetFile(fname);    
        return 0;
    }
    
    public static void process(int numEngines,boolean interactive)
    {
        EthernetSwitch[] enetSwitches = new EthernetSwitch[2];
        
        if(interactive)
        {
            int i = 0; 
            String choice;
            do
            {
                System.out.println("Please enter new IP Address : ");
                String ip = DEC.readInput();

                if(InetAddressValidator.getInstance().isValid(ip))
                {
                    enetSwitches[i++] = new EthernetSwitch(ip);
                }

                System.out.println("Do you want to continue adding switches ? : ");
                choice = DEC.readInput();
            }while(choice.toLowerCase().equals("y") && i < enetSwitches.length);
        }
        else
        {
            enetSwitches[0] = new EthernetSwitch("192.168.176.176");
            enetSwitches[1] = new EthernetSwitch("192.168.176.176");
        }
            
        for(EthernetSwitch es : enetSwitches)
        {
            if(es.ping())
            {
                es.configure();
            }
        }            
    }
    
    /**
     * Config Ethernet switch with config defined in request Array
     * Engine number should start with 1 (max 8)
     *         int request [][] = new int [3][];
     *         request [0] = new int [2];
     *         request [1] = new int [2];
     *         request [2] = new int [4];
     *         request [0][0] = 1;
     *         request [0][1] = 2;
     *         request [1][0] = 3;
     *         request [1][1] = 4;
     *         request [2][0] = 5;
     *         request [2][1] = 6;
     *         request [2][2] = 7;
     *         request [2][3] = 8;
     * 
     * In the above example the configuration is engine 1,2 are one system
     * 3,4 are another system
     * 5,6,7,8 are the last system
     * 
     * @param request - will define requested configuration
     * @return 
     */
    public String [] createConfigCommands (int request[][])
    {
        int numOfSetups = request.length;
        String sPort = "";
        boolean firstLan = true;
        
        String res [] = new String [100];
        int resNum = 0;
        
        for (int i = 0; i < numOfSetups; ++i)
        {
            res [resNum++] = "create vlan=xzone" + (i+1) + " vid=" + (i+2);
            sPort  = "";
            for (int j = 0; j < request [i].length; j++)
            {
                int engine = request [i][j];
                if (engine > 0 && engine < 9)
                {
                    int p1, p2;
                    p1 = engine * 2 - 1;
                    p2 = engine * 2;
                    
                    sPort += "," + p1 + "," + p2;
                }
            }
            
            // remove the first comma
            sPort = sPort.substring(1);
            if (firstLan)
            {
                // add the other 8 ports to the first Lun
                sPort += ",17-24";
                firstLan = false;
            }
            
            res [resNum++] = "add vlan=" + (i+2) + " port " + sPort;
        }
        
        res [resNum++] = "add ip interface=vlan2 ipaddress="+serverIP+" netmask 255.255.255.0";
        
        String resf [] = new String [resNum];
        System.arraycopy(res, 0, resf, 0, resNum);  
        
        return resf;
    } 

    @Override
    public boolean ping() {
         int res = tln.myPing(serverIP, 0);         
         return res > 0 ? true : false; 
    }
    
    @Override
    public boolean connect() 
    {
        connected = tln.initializeCommunicationTo(serverIP, port);
        tln.loginEthernetSwitch("manager", "friend", "manager>");
        return connected; 
    }

    public boolean disconnect() {
        return tln.disconnect();
    }
    
    @Override
    public void configure() 
    {
        int[][] request = EngineConfiguration.Request(configuration.AllThreeEngine,4);
        String[] commands = createConfigCommands(request);
        String[] dynamicConf = {"show conf","show dynamic conf"};
        
        for(String command: commands)
            l.info(command);
        
        if(!connected)
            connect();
        
        tln.runTelnetCommands(commands);
        tln.runTelnetCommands(dynamicConf);
    }

    @Override
    public void reboot() {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}